home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / include / qvaluevector.h.z / qvaluevector.h
Encoding:
C/C++ Source or Header  |  2002-04-08  |  10.0 KB  |  520 lines

  1. /****************************************************************************
  2. **
  3. ** Definition of QValueVector class
  4. **
  5. **
  6. ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
  7. **
  8. ** This file is part of the tools module of the Qt GUI Toolkit.
  9. **
  10. ** This file may be distributed under the terms of the Q Public License
  11. ** as defined by Trolltech AS of Norway and appearing in the file
  12. ** LICENSE.QPL included in the packaging of this file.
  13. **
  14. ** This file may be distributed and/or modified under the terms of the
  15. ** GNU General Public License version 2 as published by the Free Software
  16. ** Foundation and appearing in the file LICENSE.GPL included in the
  17. ** packaging of this file.
  18. **
  19. ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
  20. ** licenses may use this file in accordance with the Qt Commercial License
  21. ** Agreement provided with the Software.
  22. **
  23. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  24. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25. **
  26. ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
  27. **   information about Qt Commercial License Agreements.
  28. ** See http://www.trolltech.com/qpl/ for QPL licensing information.
  29. ** See http://www.trolltech.com/gpl/ for GPL licensing information.
  30. **
  31. ** Contact info@trolltech.com if any conditions of this licensing are
  32. ** not clear to you.
  33. **
  34. **********************************************************************/
  35.  
  36. #ifndef QVALUEVECTOR_H
  37. #define QVALUEVECTOR_H
  38.  
  39. #ifndef QT_H
  40. #include "qtl.h"
  41. #include "qshared.h"
  42. #include "qdatastream.h"
  43. #endif // QT_H
  44.  
  45. #ifndef QT_NO_STL
  46. #include <vector>
  47. #endif
  48.  
  49. template <class T>
  50. class Q_EXPORT QValueVectorPrivate : public QShared
  51. {
  52. public:
  53.  
  54.     typedef T value_type;
  55.     typedef T* pointer;
  56.  
  57.     QValueVectorPrivate()
  58.     : start( 0 ), finish( 0 ), end( 0 )
  59.     {
  60.     }
  61.  
  62.     QValueVectorPrivate( const QValueVectorPrivate<T>& x )
  63.     : QShared()
  64.     {
  65.     if ( x.size() > 0 ) {
  66.         start = new T[ x.size() ];
  67.         finish = start + x.size();
  68.         end = start + x.size();
  69.         qCopy( x.start, x.finish, start );
  70.     } else {
  71.         start = 0;
  72.         finish = 0;
  73.         end = 0;
  74.     }
  75.     }
  76.  
  77.     QValueVectorPrivate( size_t size )
  78.     {
  79.     if ( size > 0 ) {
  80.         start = new T[size];
  81.         finish = start + size;
  82.         end = start + size;
  83.     } else {
  84.         start = 0;
  85.         finish = 0;
  86.         end = 0;
  87.     }
  88.     }
  89.  
  90.     void derefAndDelete() // ### hack to get around hp-cc brain damage
  91.     {
  92.     if ( deref() ) {
  93.         delete this;
  94.     }
  95.     }
  96.  
  97. #if defined(Q_TEMPLATEDLL)
  98.     // Workaround MS bug in memory de/allocation in DLL vs. EXE
  99.     virtual
  100. #endif
  101.     ~QValueVectorPrivate()
  102.     {
  103.     delete[] start;
  104.     }
  105.  
  106.     size_t size() const
  107.     {
  108.     return finish - start;
  109.     }
  110.  
  111.     bool empty() const
  112.     {
  113.     return start == finish;
  114.     }
  115.  
  116.     size_t capacity() const
  117.     {
  118.     return end - start;
  119.     }
  120.  
  121.     void insert( pointer pos, const T& x )
  122.     {
  123.     const size_t lastSize = size();
  124.     const size_t n = lastSize !=0 ? 2*lastSize : 1;
  125.     const size_t offset = pos - start;
  126.     pointer newStart = new T[n];
  127.     pointer newFinish = newStart + offset;
  128.     qCopy( start, pos, newStart );
  129.     *newFinish = x;
  130.     qCopy( pos, finish, ++newFinish );
  131.     delete[] start;
  132.     start = newStart;
  133.     finish = newStart + lastSize + 1;
  134.     end = newStart + n;
  135.     }
  136.  
  137.     void insert( pointer pos, size_t n, const T& x )
  138.     {
  139.     if ( size_t( end - finish ) >= n ) {
  140.         // enough room
  141.         const size_t elems_after = finish - pos;
  142.         pointer old_finish = finish;
  143.         if ( elems_after > n ) {
  144.         qCopy( finish - n, finish, finish );
  145.         finish += n;
  146.         qCopyBackward( pos, old_finish - n, old_finish );
  147.         qFill( pos, pos + n, x );
  148.         } else {
  149.         pointer filler = finish;
  150.         size_t i = n - elems_after;
  151.         for ( ; i > 0; --i, ++filler )
  152.             *filler = x;
  153.         finish += n - elems_after;
  154.         qCopy( pos, old_finish, finish );
  155.         finish += elems_after;
  156.         qFill( pos, old_finish, x );
  157.         }
  158.     } else {
  159.         // not enough room
  160.         const size_t lastSize = size();
  161.         const size_t len = lastSize + QMAX( lastSize, n );
  162.         pointer newStart = new T[len];
  163.         pointer newFinish = qCopy( start, pos, newStart );
  164.         // fill up inserted space
  165.         size_t i = n;
  166.         for ( ; i > 0; --i, ++newFinish )
  167.         *newFinish = x;
  168.         newFinish = qCopy( pos, finish, newFinish );
  169.         delete[] start;
  170.         start = newStart;
  171.         finish = newFinish;
  172.         end = newStart + len;
  173.     }
  174.     }
  175.  
  176.     void reserve( size_t n )
  177.     {
  178.     const size_t lastSize = size();
  179.     pointer tmp = growAndCopy( n, start, finish );
  180.     start = tmp;
  181.     finish = tmp + lastSize;
  182.     end = start + n;
  183.     }
  184.  
  185.     void clear()
  186.     {
  187.     delete[] start;
  188.     start = 0;
  189.     finish = 0;
  190.     end = 0;
  191.     }
  192.  
  193.     pointer start;
  194.     pointer finish;
  195.     pointer end;
  196.  
  197. private:
  198.     pointer growAndCopy( size_t n, pointer s, pointer f )
  199.     {
  200.     pointer newStart = new T[n];
  201.     qCopy( s, f, newStart );
  202.     delete[] start;
  203.     return newStart;
  204.     }
  205.  
  206.     QValueVectorPrivate& operator=( const QValueVectorPrivate<T>& x );
  207.  
  208. };
  209.  
  210. template <class T>
  211. class Q_EXPORT QValueVector
  212. {
  213. public:
  214.     typedef T value_type;
  215.     typedef value_type* pointer;
  216.     typedef const value_type* const_pointer;
  217.     typedef value_type* iterator;
  218.     typedef const value_type* const_iterator;
  219.     typedef value_type& reference;
  220.     typedef const value_type& const_reference;
  221.     typedef size_t size_type;
  222. #ifndef QT_NO_STL
  223.     typedef ptrdiff_t  difference_type;
  224. #else
  225.     typedef int difference_type;
  226. #endif
  227.  
  228.     QValueVector()
  229.     {
  230.     sh = new QValueVectorPrivate<T>;
  231.     }
  232.  
  233.     QValueVector( const QValueVector<T>& v )
  234.     {
  235.     sh = v.sh;
  236.     sh->ref();
  237.     }
  238.  
  239.     QValueVector( size_type n, const T& val = T() )
  240.     {
  241.     sh = new QValueVectorPrivate<T>( n );
  242.     qFill( begin(), end(), val );
  243.     }
  244.  
  245. #ifndef QT_NO_STL
  246.     QValueVector( std::vector<T>& v )
  247.     {
  248.     sh = new QValueVectorPrivate<T>( v.size() );
  249.     qCopy( v.begin(), v.end(), begin() );
  250.     }
  251. #endif
  252.  
  253.     ~QValueVector()
  254.     {
  255.     sh->derefAndDelete();
  256.     }
  257.  
  258.     QValueVector<T>& operator= ( const QValueVector<T>& v )
  259.     {
  260.     v.sh->ref();
  261.     sh->derefAndDelete();
  262.     sh = v.sh;
  263.     return *this;
  264.     }
  265.  
  266. #ifndef QT_NO_STL
  267.     QValueVector<T>& operator= ( const std::vector<T>& v )
  268.     {
  269.     clear();
  270.     resize( v.size() );
  271.     qCopy( v.begin(), v.end(), begin() );
  272.     return *this;
  273.     }
  274. #endif
  275.  
  276.     size_type size() const
  277.     {
  278.     return sh->size();
  279.     }
  280.  
  281.     bool empty() const
  282.     {
  283.     return sh->empty();
  284.     }
  285.  
  286.     size_type capacity() const
  287.     {
  288.     return size_type( sh->capacity() );
  289.     }
  290.  
  291.     iterator begin()
  292.     {
  293.     detach();
  294.     return sh->start;
  295.     }
  296.  
  297.     const_iterator begin() const
  298.     {
  299.     return sh->start;
  300.     }
  301.  
  302.     iterator end()
  303.     {
  304.     detach();
  305.     return sh->finish;
  306.     }
  307.  
  308.     const_iterator end() const
  309.     {
  310.     return sh->finish;
  311.     }
  312.  
  313.     reference at( size_type i, bool* ok = 0 )
  314.     {
  315.     detach();
  316.     if ( ok ) {
  317.         if ( i < size() )
  318.         *ok = TRUE;
  319.         else
  320.         *ok = FALSE;
  321.     }
  322.     return *( begin() + i );
  323.     }
  324.  
  325.     const_reference at( size_type i, bool* ok = 0 ) const
  326.     {
  327.     if ( ok ) {
  328.         if ( i < size() )
  329.         *ok = TRUE;
  330.         else
  331.         *ok = FALSE;
  332.     }
  333.     return *( begin() + i );
  334.     }
  335.  
  336.     reference operator[]( size_type i )
  337.     {
  338.     detach();
  339.     return *( begin() + i );
  340.     }
  341.  
  342.     const_reference operator[]( size_type i ) const
  343.     {
  344.     return *( begin() + i );
  345.     }
  346.  
  347.     reference front()
  348.     {
  349.     Q_ASSERT( !empty() );
  350.     detach();
  351.     return *begin();
  352.     }
  353.  
  354.     const_reference front() const
  355.     {
  356.     Q_ASSERT( !empty() );
  357.     return *begin();
  358.     }
  359.  
  360.     reference back()
  361.     {
  362.     Q_ASSERT( !empty() );
  363.     detach();
  364.     return *( end() - 1 );
  365.     }
  366.  
  367.     const_reference back() const
  368.     {
  369.     Q_ASSERT( !empty() );
  370.     return *( end() - 1 );
  371.     }
  372.  
  373.     void push_back( const T& x )
  374.     {
  375.     detach();
  376.     if ( sh->finish == sh->end ) {
  377.         sh->reserve( size()+1 );
  378.     }
  379.     *sh->finish = x;
  380.     ++sh->finish;
  381.     }
  382.  
  383.     void pop_back()
  384.     {
  385.     detach();
  386.     if ( empty() )
  387.         return;
  388.     --sh->finish;
  389.     }
  390.  
  391.     iterator insert( iterator pos, const T& x )
  392.     {
  393.     size_type offset = pos - sh->start;
  394.     detach();
  395.     if ( pos == end() ) {
  396.         if ( sh->finish == sh->end )
  397.         push_back( x );
  398.         else {
  399.         *sh->finish = x;
  400.         ++sh->finish;
  401.         }
  402.     } else {
  403.         if ( sh->finish == sh->end ) {
  404.         sh->insert( pos, x );
  405.         } else {
  406.         *sh->finish = *(sh->finish - 1);
  407.         ++sh->finish;
  408.         qCopyBackward( pos, sh->finish - 2, sh->finish - 1 );
  409.         *pos = x;
  410.         }
  411.     }
  412.     return begin() + offset;
  413.     }
  414.  
  415.     iterator insert( iterator pos, size_type n, const T& x )
  416.     {
  417.         if ( n != 0 ) {
  418.                 size_type offset = pos - sh->start;
  419.             detach();
  420.             pos = begin() + offset;
  421.             sh->insert( pos, n, x );
  422.         }
  423.         return pos;
  424.     }
  425.  
  426.     void reserve( size_type n )
  427.     {
  428.     if ( capacity() < n ) {
  429.         detach();
  430.         sh->reserve( n );
  431.     }
  432.     }
  433.  
  434.     void resize( size_type n, const T& val = T() )
  435.     {
  436.     if ( n < size() )
  437.         erase( begin() + n, end() );
  438.     else
  439.         insert( end(), n - size(), val );
  440.     }
  441.  
  442.     void clear()
  443.     {
  444.     detach();
  445.     sh->clear();
  446.     }
  447.  
  448.     iterator erase( iterator pos )
  449.     {
  450.     detach();
  451.     if ( pos + 1 != end() )
  452.         qCopy( pos + 1, sh->finish, pos );
  453.     --sh->finish;
  454.     return pos;
  455.     }
  456.  
  457.     iterator erase( iterator first, iterator last )
  458.     {
  459.     detach();
  460.     qCopy( last, sh->finish, first );
  461.     sh->finish = sh->finish - ( last - first );
  462.     return first;
  463.     }
  464.  
  465.     bool operator==( const QValueVector<T>& x )
  466.     {
  467.     return qEqual( begin(), end(), x.begin() );
  468.     }
  469.  
  470.     bool operator==( const QValueVector<T>& x ) const
  471.     {
  472.     return qEqual( begin(), end(), x.begin() );
  473.     }
  474.  
  475. protected:
  476.     void detach()
  477.     {
  478.     if ( sh->count > 1 ) {
  479.         sh->deref();
  480.         sh = new QValueVectorPrivate<T>( *sh );
  481.     }
  482.     }
  483.     QValueVectorPrivate<T>* sh;
  484. };
  485.  
  486.  
  487. #ifndef QT_NO_DATASTREAM
  488. template<class T>
  489. inline QDataStream& operator>>( QDataStream& s, QValueVector<T>& v )
  490. {
  491.     v.clear();
  492.     Q_UINT32 c;
  493.     s >> c;
  494.     v.resize( c );
  495.     for( Q_UINT32 i = 0; i < c; ++i )
  496.     {
  497.     T t;
  498.     s >> t;
  499.     v[i] = t;
  500.     }
  501.     return s;
  502. }
  503.  
  504. template<class T>
  505. inline QDataStream& operator<<( QDataStream& s, const QValueVector<T>& v )
  506. {
  507.     s << (Q_UINT32)v.size();
  508.     // ### use typename QValueVector<T>::const_iterator once all supported
  509.     // ### compilers know about the 'typename' keyword.
  510.     const T* it = v.begin();
  511.     for( ; it != v.end(); ++it )
  512.     s << *it;
  513.     return s;
  514. }
  515. #endif // QT_NO_DATASTREAM
  516.  
  517.  
  518.  
  519. #endif
  520.